package com.cx.caigou.request.service.impl;

import com.cx.caigou.config.ResultVO;
import com.cx.caigou.config.ResultVOBuilder;
import com.cx.caigou.request.mapper.RequestMapper;
import com.cx.caigou.request.model.*;
import com.cx.caigou.request.service.RequestService;
import com.cx.caigou.util.*;
import io.swagger.models.auth.In;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import java.util.*;

@Service
public class RequestServiceImpl implements RequestService {
    @Autowired
    private RequestMapper requestMapper;

    @Override
    public ResultVO queryData(RequestSelect requestSelect) {

        List<RequestClass> requestList = requestMapper.queryData(requestSelect);
        //将状态改为所需String
        for (RequestClass request : requestList) {
            request.setInquiryStatusName(StatusEnum.getStatusName(request.getInquiryStatus()));
        }

//        for (RequestClass request : requestList) {
//            if (request.getInquiryStatus()==StatusEnum.WEiBAOJIA.getStatus()) {
//                request.setInquiryStatusName(StatusEnum.WEiBAOJIA.getStatusName());
//
//            }else if (request.getInquiryStatus()==StatusEnum.YIBAOCUN.getStatus()){
//                request.setInquiryStatusName(StatusEnum.YIBAOCUN.getStatusName());
//
//            }else if(request.getInquiryStatus()==StatusEnum.YITIJIAO.getStatus()){
//                request.setInquiryStatusName(StatusEnum.YITIJIAO.getStatusName());
//
//            }else if(request.getInquiryStatus()==StatusEnum.YISHENHE.getStatus()){
//                request.setInquiryStatusName(StatusEnum.YISHENHE.getStatusName());
//
//            }else if(request.getInquiryStatus()==StatusEnum.YIZUOFEI.getStatus()){
//                request.setInquiryStatusName(StatusEnum.YIZUOFEI.getStatusName());
//            }
//        }
        int count =  requestMapper.queryCount(requestSelect);

        AllrecordsVo allrecordsVo = new AllrecordsVo();
        allrecordsVo.setPageIndex(requestSelect.getPageIndex());
        allrecordsVo.setPageSize(requestSelect.getPageSize());
        allrecordsVo.setTotalNumber(count);
        allrecordsVo.setDataList(requestList);
        allrecordsVo.resettotalNum(count);

        return ResultVOBuilder.success(allrecordsVo);



    }

    @Override
    public ResultVO queryLegalPerson(Integer id) {
        List<LegalPersonVO> legalPersonVO = requestMapper.query(id);

        return ResultVOBuilder.success(legalPersonVO);

    }

    @Override
    public ResultVO queryByLegalPerson(Integer id) {
        List<String> gysPersons =  requestMapper.queryByLegalPerson(id);
        HashSet<String> gysPerson= new HashSet<>(gysPersons);
        return ResultVOBuilder.success(gysPerson);
    }

    @Override
    public ResultVO selectMaterial(SelectSpare selectSpare) {
        List<SpareClass> requestList = requestMapper.querySpareData(selectSpare);

        int count =  requestMapper.querySpareCount(selectSpare);

        AllrecordsVo allrecordsVo = new AllrecordsVo();
        allrecordsVo.setPageIndex(selectSpare.getPageIndex());
        allrecordsVo.setPageSize(selectSpare.getPageSize());
        allrecordsVo.setTotalNumber(count);
        allrecordsVo.setDataList(requestList);
        allrecordsVo.resettotalNum(count);

        return ResultVOBuilder.success(allrecordsVo);

    }

    @Override
    public ResultVO searchPartnerPage(SelectSupplier selectSupplier) {
        List<SupplierClass> requestList = requestMapper.querySupplierData(selectSupplier);

        int count =  requestMapper.querySupplierCount(selectSupplier);

        AllrecordsVo allrecordsVo = new AllrecordsVo();
        allrecordsVo.setPageIndex(selectSupplier.getPageIndex());
        allrecordsVo.setPageSize(selectSupplier.getPageSize());
        allrecordsVo.setTotalNumber(count);
        allrecordsVo.setDataList(requestList);
        allrecordsVo.resettotalNum(count);

        return ResultVOBuilder.success(allrecordsVo);
    }

    @Override
    public ResultVO see(Integer requestForQuotationId) {
        List<SeeClass> seeClasse = requestMapper.queryByRequestId(requestForQuotationId);
        List<SpareVo> spareVoList  = requestMapper.queryInquiryDetailsList(requestForQuotationId);
//        for (SpareVo s:spareVoList) {
//            List<SpareClass> spare = requestMapper.queryspare(s.getId());
//            for (SpareClass str:spare ){
//                s.setSpareCoding(str.getCode());
//                s.setSpareName(str.getName());
//            }
//        }
        List<SupplierVo> supplierVoList = requestMapper.querySupplierDetailsList(requestForQuotationId);
        for (SeeClass s:seeClasse) {
            s.setInquiryDetailsList(spareVoList);
            s.setSupplierDetailsList(supplierVoList);

            s.setIsTaxName(TaxEnum.getStatusName(s.getIsTax()));
            s.setTypeName(TypeEnum.getStatusName(s.getType()));
            if(s.getCurrencyCode().equals("0")){
                s.setCurrencyCode("人民币");
            }else if(s.getCurrencyCode().equals("1")){
                s.setCurrencyCode("美元");
            }else if(s.getCurrencyCode().equals("2")){
                s.setCurrencyCode("日元");
            }else if(s.getCurrencyCode().equals("3")){
                s.setCurrencyCode("港元");
            }

        }
        System.out.println(seeClasse);



        return ResultVOBuilder.success(seeClasse);
    }
    @Transactional
    @Override
    public ResultVO add(AllClass allClass) {
        /* 1.验证询价类型是否存在3.验证币别是否存在4.验证金额是否含税是否存在5.验证询价开始日期是否在结束日期之前*/
        ResultVO resultVo = validateEnum(allClass);
        if (!resultVo.isSuccess()){
            return resultVo;
        }
        /* 1.验证询价备件明细是否为空==以通过表单验证解决2.验证询价供应商明细是否为空==以通过表单验证解决3.验证备件数量是否为空4.验证备件是否重复5.验证供应商是否重复*/
        ResultVO resultVo1 = validateIsNull(allClass);
        if (!resultVo1.isSuccess()){
            return resultVo1;
        }
        //验证备件是否存在,验证供应商是否存在
//        ResultVO resultVo2 = validateCunZai(allClass);
//        if (!resultVo2.isSuccess()){
//            return resultVo2;
//        }
//        //验证选择好备件后下面的供应商是否有生产他的供应   2验证选择好供应商后上面的备件是否它可以生产
//        ResultVO resultVo3 = validateHefa(allClass);
//        if (!resultVo3.isSuccess()){
//            return resultVo3;
//        }


        //二、创建人和时间的赋值、备件明细中外键的赋值、单号的生成等
        //三、入库到三张表中


        //验证法人是否存在
        List<LegalPersonVO> legalPersonVOS = requestMapper.queryLegalPerson(allClass.getLegalPersonId());
        if(legalPersonVOS==null){
            return ResultVOBuilder.error("该法人不存在");
        }


        while (true){
            Random random = new Random();
            int ri = random.nextInt(999999999);
            int i = requestMapper.queryIsFind(ri);
            if(i==0){
                allClass.setRequestForQuotationId(ri);
                break;
            }
        }


        allClass.setCreateTime(new Date());
        allClass.setCreatorName("询价人");
/*        //根据编码查处响应的外建id
        ResultVO resultVO =  selectAllCode(allClass);
        if(!resultVO.isSuccess()){
            return resultVO;
        }*/
        allClass.setSpareId(1);
        allClass.setSupplierId(1);


        System.out.println(allClass);
        requestMapper.addTou(allClass);
        requestMapper.addSpare(allClass.getInquiryDetailsList(),allClass.getRequestForQuotationId(),allClass.getSpareId());
        requestMapper.addSupplier(allClass.getSupplierDetailsList(),allClass.getRequestForQuotationId(),allClass.getSupplierId());
        return ResultVOBuilder.success();
    }

    private ResultVO selectAllCode(AllClass allClass){

        List<String> codeList = requestMapper.queryCode();
        //备件
        List<SpareVo> inquiryDetailsList = allClass.getInquiryDetailsList();
        for (String s:codeList) {
            for (SpareVo spare : inquiryDetailsList) {
                if(spare.getSpareCoding() == s){
                    spare.setSpareId(1);
                }
            }
        }
       return ResultVOBuilder.success();
    }

    private ResultVO validateHefa(AllClass allClass){
        //验证选择好备件后下面的供应商是否有生产他的供应   2验证选择好供应商后上面的备件是否它可以生产

        //备件
        List<SpareVo> inquiryDetailsList = allClass.getInquiryDetailsList();
        List<String> codeSpares = new ArrayList<>();
        for (SpareVo spare : inquiryDetailsList) {
            codeSpares.add(spare.getSpareCoding());
        }
        //查出响应的外键
        List<Integer>  spareId =  requestMapper.querySpareId(codeSpares);
        HashSet<Integer> spareIds = new HashSet<>(spareId);
        //根据外建查询编码
        List<String> partCodeList = requestMapper.queryBeiAllCode(spareIds);
        //供应商
        List<SupplierVo> supplierDetailsList = allClass.getSupplierDetailsList();
        List<String> codeSupplier  = new ArrayList<>();
        for (SupplierVo supplier : supplierDetailsList) {
            codeSpares.add(supplier.getVendorCode());
        }
        //查出响应的外键
        List<Integer>  supplierId =  requestMapper.querySupplierId(codeSupplier);
        HashSet<Integer> supplierIds = new HashSet<>(supplierId);

        //根据外建查询编码
        List<String> supplierCode = requestMapper.queryGongAllCode(supplierIds);

        //根据备件批量查询中间表，查询出这些备件能被升产的供应商都有谁
        List<SpareSupplier> partSupplierList = requestMapper.queryPSByCodes(spareIds);
        //把每个备件的供应商找出来，然后和前端的供应商对比
        for (String partCode : partCodeList){
            //当前备件的供应商集合
            List<String> supplierCodeList = new ArrayList<>();
            for (SpareSupplier partSupplier: partSupplierList){
                if (partCode.equals(partSupplier.getSpareCoding())){
                    supplierCodeList.add(partSupplier.getVendorCode());
                }
            }
            //跟要添加的备件编码比较，retainAll是判断另个集合是否有交集
            if(!supplierCode.retainAll(supplierCodeList)){
                return ResultVOBuilder.error("备件"+partCode+"没有可以生产它的供应商，可以生产它的供应商为"+supplierCodeList);
            }
        }
        return  ResultVOBuilder.success();
    }
    private  ResultVO  validateCunZai(AllClass allClass){
        //验证备件是否存在,验证供应商是否存在
        List<SpareVo> inquiryDetailsList = allClass.getInquiryDetailsList();
        List<String> codeSpares = new ArrayList<>();
        for (SpareVo spare : inquiryDetailsList) {
            codeSpares.add(spare.getSpareCoding());
        }
        //外建id
        List<Integer>  spareId =  requestMapper.querySpareId(codeSpares);
        HashSet<Integer> spareIds = new HashSet<>(spareId);
        //根据外建查询编码
        List<String> list = requestMapper.queryBeiAllCode(spareIds);
        if (list.size()!=codeSpares.size()){
            codeSpares.removeAll(list);
            return ResultVOBuilder.error("有不存在的备件集合，不存在的备件是："+codeSpares);
        }
        //供应商
        List<SupplierVo> supplierDetailsList = allClass.getSupplierDetailsList();
        List<String> codeSupplier  = new ArrayList<>();
        for (SupplierVo supplier : supplierDetailsList) {
            codeSpares.add(supplier.getVendorCode());
        }
        //外建id
        List<Integer>  supplierId =  requestMapper.querySupplierId(codeSupplier);
        HashSet<Integer> supplierIds = new HashSet<>(supplierId);
        //根据外建查询编码
        List<String> list1 = requestMapper.queryGongAllCode(supplierIds);
        if (list1.size()!=codeSupplier.size()){
            codeSupplier.removeAll(list1);
            return ResultVOBuilder.error("有不存在的备件集合，不存在的备件是："+codeSupplier);
        }

        return ResultVOBuilder.success();
    }
    private ResultVO validateIsNull(AllClass allClass){
        /* 1.验证询价备件明细是否为空==以通过表单验证解决2.验证询价供应商明细是否为空==以通过表单验证解决
        3.验证备件数量是否为空4.验证备件是否重复5.验证供应商是否重复*/

        //验证备件是否重复
        List<SpareVo> spareList = allClass.getInquiryDetailsList();
        List<String> spareCode = new ArrayList<>();
        for (SpareVo spareVo : spareList) {
            if(spareVo.getInquiryQty()==null){
                ResultVOBuilder.error("备件数量不能为空");
            }
            spareCode.add(spareVo.getSpareCoding());
        }
        List<String> code1 = new ArrayList<>();
        List<String> code2= new ArrayList<>();
        for (String sc: spareCode) {
            if(code1.contains(sc)){
                code2.add(sc);
            }else{
                code1.add(sc);
            }
        }
        if(code2.size() > 0){
            return ResultVOBuilder.error("存在重复的备件编码"+code2);
        }

    //验证供应商是否重复
        List<SupplierVo> supplierList = allClass.getSupplierDetailsList();
        List<String> supplierCode = new ArrayList<>();
        for (SupplierVo supplier : supplierList) {
            supplierCode.add(supplier.getVendorCode());
        }
        List<String> code3 = new ArrayList<>();
        List<String> code4= new ArrayList<>();
        for (String sc: supplierCode) {
            if(code3.contains(sc)){
                code4.add(sc);
            }else{
                code3.add(sc);
            }
        }
        if(code2.size() > 0){
            return ResultVOBuilder.error("存在重复的供应商编码"+code4);
        }
        return ResultVOBuilder.success();
    }
    private  ResultVO validateEnum(AllClass allClass){
        /* 1.验证询价类型是否存在
        3.验证币别是否存在
        4.验证金额是否含税是否存在
        5.验证询价开始日期是否在结束日期之前*/
        if(CurrencyCodeEnum.getStatusName(allClass.getCurrencyCode())==null){
            return ResultVOBuilder.error("币别不存在!");
        }
        if(TaxEnum.getStatusName(allClass.getCurrencyCode())==null){
            return ResultVOBuilder.error("是否含税不存在");
        }
        if(TypeEnum.getStatusName(allClass.getCurrencyCode())==null){
            return  ResultVOBuilder.error("类型不存在");
        }
        if(allClass.getEndTime().before(allClass.getStartTime())){
           return ResultVOBuilder.error("结束时间不能再开始时间之前");
        }
        return ResultVOBuilder.success();
    }

    @Transactional
    @Override
    public ResultVO update(AllClass allClass) {

        //头表 直接修改
        requestMapper.updateTou(allClass);

        //询价备件  先删除所有的备件  在添加相应的备件
        requestMapper.deleteAllSpare(allClass.getInquiryDetailsList(),allClass.getRequestForQuotationId());
        requestMapper.addAllSpare(allClass.getInquiryDetailsList(),allClass.getRequestForQuotationId());
        //询价供应商 先删除所有的供应商 再添加相应的供应商
        requestMapper.deleteAllSupplier(allClass.getSupplierDetailsList(),allClass.getRequestForQuotationId());
        requestMapper.addAllSupplier(allClass.getSupplierDetailsList(),allClass.getRequestForQuotationId());
        return ResultVOBuilder.success();
    }

    /**
     *   2.提示版本问题，询问产品经理支持哪种版本的导入格式，2007版本的导入模板，根据版本不同，poi导入技术的读取方式不同
     3.模板是否是需要导入的模板，验证模板是否正确
     4.格式问题，必须保持统一格式，统一为字符串格式导入
     5.验证不为空字段是否为空
     6.验证字符长度是否符合需求
     7.验证数据是否存在也就是是否合法
     8.验证数据是否重复
     9.对于需要转换的数据进行数据转换，比如数据库存的数据为数字格式，用户输入的为汉字，需要把汉字转换为数字存储

     * @param file
     * @return
     */
    @Override
    public ResultVO importFile(MultipartFile file) throws Exception {
        //怎样验证模板是否正确呢？
        //引入poi读取表格数据，验证内容是否是计划大类的内容。
        //引入poi步骤  1.导包  2.引入xssf工具类完成读取
        ResultVO resultVo = poiImport(file);
        if (!resultVo.isSuccess()){
            return resultVo;
        }

        //数据放入集合中
        List<RequestSpare> All = (List<RequestSpare>) resultVo.getData();


        //有了数据就要验证数据了
        // 5.验证不为空字段是否为空

//        6.验证字符长度是否符合需求
//        7.验证数据是否存在也就是是否合法
//        8.验证数据是否重复
        ResultVO  reAll =  quchong(All);
        if(!reAll.isSuccess()){
            return reAll;
        }


//        9.对于需要转换的数据进行数据转换，比如数据库存的数据为数字格式，用户输入的为汉字，需要把汉字转换为数字存储
        List<RequestSpare> sussceList  = (List<RequestSpare>) reAll.getData();
        for (RequestSpare s : sussceList) {

        }
        //打印所有的数据进行查看
        System.out.println("看看状态是否改变了"+sussceList);

        //批量入库
        int i = 0;
        int requestForQuotationId = 99;
        int spareId = 1;
        for (RequestSpare list:sussceList) {
            if(i>10000){
                return  ResultVOBuilder.success("最大只支持导入一万条数据,前一万条数据已经入库");
            }
            requestMapper.addAll(list);
            i++;
            requestForQuotationId++;
        }




        return  ResultVOBuilder.success();
    }


    //poi读取信息
    public ResultVO poiImport(MultipartFile file)throws Exception{
        //        3.模板是否是需要导入的模板，验证模板是否正确
        XSSFWorkbook workbook = new XSSFWorkbook(file.getInputStream());
        //获取单元格中的信息 at0是获取sheet1中的数据。
        XSSFSheet sheet = workbook.getSheetAt(0);
        System.out.println(sheet.getRow(sheet.getFirstRowNum()).getCell(0));
        //验证第一列第一行的表格标头信息是否为 “询价单导入”，如果不是，提示模板错误。
        if (!String.valueOf(sheet.getRow(sheet.getFirstRowNum()).getCell(0)).equals("询价备件明细导入")) {
            return ResultVOBuilder.error("模板错误，请检查模板！");
        }
        //定义一个集合用来存放表格中的数据
        List<RequestSpare> planClassVoList = new ArrayList<>();
        //遍历excel表格中的所有数据，从第五行开始读取，没有数据时终止遍历。
        for (int i = sheet.getFirstRowNum() + 4; i <= sheet.getLastRowNum(); i++) {
            //读取每一行的数据
            XSSFRow xssfRow = sheet.getRow(i);
            if(xssfRow!=null) {
                String test1 = String.valueOf(xssfRow.getCell(1)).trim();
                String test2 = String.valueOf(xssfRow.getCell(2)).trim();
                String test3 = String.valueOf(xssfRow.getCell(3)).trim();
                String test4 = String.valueOf(xssfRow.getCell(4)).trim();
                String test5 = String.valueOf(xssfRow.getCell(5)).trim();

                if (!test1.equals("")&&!test1.equals("null")
                        ||!test2.equals("")&&!test2.equals("null")
                        ||!test3.equals("")&&!test3.equals("null")
                        ||!test4.equals("")&&!test4.equals("null")
                        ||!test5.equals("")&&!test5.equals("null")

                       ){
                    //把每一行的数据放入到实体类中
                    ResultVO<RequestSpare> inquiryImportVo = build(xssfRow);
                    if (!inquiryImportVo.isSuccess()){
                        return inquiryImportVo;
                    }
                    //把实体类中的数据放入到list集合中
                    planClassVoList.add(inquiryImportVo.getData());
                }

            }
        }
        return ResultVOBuilder.success(planClassVoList);
    }

    public ResultVO build(XSSFRow xssfRow){
        RequestSpare planClassAddVo = new RequestSpare();
        //        4.格式问题，必须保持统一格式，统一为字符串格式导入
        planClassAddVo.setSpareName(String.valueOf(xssfRow.getCell(1)));
        planClassAddVo.setSpareCoding(String.valueOf(xssfRow.getCell(2)));

        String s = String.valueOf(xssfRow.getCell(3));
        int i = Integer.valueOf(s).intValue();
        planClassAddVo.setInquiryQty(i);

        String s1 = String.valueOf(xssfRow.getCell(4));
        int i1 = Integer.valueOf(s1).intValue();
        planClassAddVo.setMoq(i1);

        String s2 = String.valueOf(xssfRow.getCell(5));
        int i2 = Integer.valueOf(s2).intValue();
        planClassAddVo.setDeliveryCycle(i2);

        return ResultVOBuilder.success(planClassAddVo);
    }
    /**
     *查看是否重复或者  为空
     */
    public ResultVO quchong(List<RequestSpare> All){
        //检查文档是否有重复
        List<String> codeList = new ArrayList<>();
        List<String> nameList = new ArrayList<>();

        for (RequestSpare a:All) {
            codeList.add(a.getSpareCoding());
            nameList.add(a.getSpareName());
        }
        //去重code
        HashSet<String> codeSet = new HashSet<>(codeList);
        //去重name
        HashSet<String> nameSet = new HashSet<>(nameList);

        //去重后放入集合中
        if(codeList.size()!= codeSet.size()){
            ResultVOBuilder.error("有重复的编码,请检查你的文档");
        }
        if(nameList.size()!=nameSet.size()){
            ResultVOBuilder.error("有重复的名称,请检查你的文档");
        }

        //检查文档与数据库中是否有重复的名称及编码
        //查询数据库里的所有编码以及名称
        List<String> AllCode = requestMapper.queryCode();
        List<String> AllName = requestMapper.queryName();

        //将excl表中的编码,名称;加到查出来的编码,名称集合
        for ( String  list:codeList ) {
            AllCode.add(list);
        }
        for ( String  list:nameList ) {
            AllName.add(list);
        }
        //对所有的code去重后比较大小
        HashSet<String> quchongCode = new HashSet<>(AllCode);

        if(quchongCode.size() != AllCode.size()){

            //存放的重复的集合
            List<String> repeatCodeList = new ArrayList<>();
            //存放的不重复的集合
            List<String> codeList2 = new ArrayList<>();

            for (String  a :AllName){
                if (a.contains(a)){
                    //包含证明重复了
                    repeatCodeList.add(a);
                }else {
                    //不包含证明不重复
                    codeList2.add(a);
                }
            }

            return ResultVOBuilder.error("库中已存在相应的编码,文档中重复的编码是"+repeatCodeList);
        }

        //对所有的name去重后比较大小
        HashSet<String> quchongName = new HashSet<>(AllName);

        if(quchongName.size() != AllName.size()){
            //删除
            //存放的重复的集合
            List<String> repeatNameList = new ArrayList<>();
            //存放的不重复的集合
            List<String> nameList2 = new ArrayList<>();

            for (String  a :AllCode){
                if (a.contains(a)){
                    //包含证明重复了
                    repeatNameList.add(a);
                }else {
                    //不包含证明不重复
                    nameList2.add(a);
                }
            }

            if (repeatNameList.size()>0){
                return ResultVOBuilder.error("库中已存在相应的名称,文档中重复的是"+repeatNameList);
            }

        }
        return ResultVOBuilder.success(All);
    }




    @Override
    public ResultVO modifyState(ID requestForQuotationId) {
        //作废
        requestMapper.modifyState(requestForQuotationId);
    return ResultVOBuilder.success();
    }

    @Override
    public ResultVO updateState(ID requestForQuotationId) {
        //审核
        requestMapper.updateState(requestForQuotationId);
        return ResultVOBuilder.success();
    }

    @Override
    public ResultVO approverState(ID requestForQuotationId) {
        //审批
        requestMapper.approverState(requestForQuotationId);
        return ResultVOBuilder.success();
    }
}
